<template>
	<view class="expandable-text">
		<!-- 文本容器 -->
		<view ref="textWrapper" class="text-wrapper" :style="{ maxHeight: isExpanded ? fullHeight : maxClampHeight }"
			@transitionend="onTransitionEnd">
			<text ref="textContent" class="content" :style="{ fontSize: fontSize + 'rpx', color: textColor }">
				{{ text }}
			</text>
		</view>

		<!-- 展开/收起按钮 -->
		<text class="toggle-btn" :style="{ color: toggleColor, fontSize: fontSize + 'rpx' }"
			@click="toggle">
			{{ isExpanded ? '【收起】' : '【展开】' }}
		</text>
	</view>
</template>

<script setup>
	import {
		ref,
		computed,
		onMounted,
		watch
	} from 'vue'

	const props = defineProps({
		text: {
			type: String,
			required: true
		},
		defaultLines: {
			type: Number,
			default: 3
		},
		fontSize: {
			type: [Number, String],
			default: 24
		},
		textColor: {
			type: String,
			default: '#464646'
		},
		toggleColor: {
			type: String,
			default: '#ff0000'
		}
	})

	const isExpanded = ref(false)
	const showToggle = ref(false)
	const textContent = ref(null)
	const textWrapper = ref(null)

	// 计算最大高度（默认显示 3 行）
	const lineHeight = 1.6 // 行高倍数
	const maxClampHeight = computed(() => {
		const em = parseFloat(props.fontSize) / 2 // rpx -> px 近似换算
		return `${em * lineHeight * props.defaultLines}px`
	})

	// 完整高度（用于展开状态）
	const fullHeight = ref('none')

	// 判断是否需要显示按钮
	const checkOverflow = () => {
		if (!textContent.value || !textContent.value.$el) return

		const element = textContent.value.$el
		const wrapper = textWrapper.value.$el

		setTimeout(() => {
			showToggle.value = element.scrollHeight > wrapper.clientHeight
		}, 10)
	}

	// 获取完整高度（用于动画）
	const getFullHeight = () => {
		if (!textContent.value || !textContent.value.$el) return
		const element = textContent.value.$el
		fullHeight.value = `${element.scrollHeight}px`
	}

	// 点击切换
	const toggle = () => {
		isExpanded.value = !isExpanded.value
		checkOverflow()
		if (isExpanded.value) {
			getFullHeight()
		}
	}

	// 监听动画结束事件（避免 DOM 未更新）
	const onTransitionEnd = () => {
		if (isExpanded.value) {
			// 展开完成后重新定位按钮
			checkOverflow()
		}
	}

	onMounted(() => {
		checkOverflow()
	})

	watch(
		() => props.text,
		() => {
			isExpanded.value = false
			checkOverflow()
		}
	)
</script>

<style scoped lang="scss">
	.expandable-text {
		position: relative;
		line-height: 1.5;
		word-wrap: break-word;
	}

	.text-wrapper {
		overflow: hidden;
		display: -webkit-box;
		-webkit-box-orient: vertical;
		-webkit-line-clamp: v-bind("isExpanded ? 100 : defaultLines");
		transition: max-height 0.3s ease-in-out;
		max-height: v-bind("maxClampHeight");
		z-index: 1;
		position: relative;
	}

	.content {
		display: block;
		word-break: break-all;
	}

	.toggle-btn {
		position: absolute;
		right: 0;
		bottom: -40rpx;
		color: #ff0000;
		background-color: transparent;
		border: none;
		padding: 0;
		margin: 0;
		z-index: 90;
		font-size: inherit;
		user-select: none;
	}
</style>